package com.yssoft.service.inventory;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.yssoft.entity.inventory.TInstockDetail;
import com.yssoft.entity.inventory.TOutInStock;
import com.yssoft.entity.inventory.TOutstock;
import com.yssoft.entity.inventory.TOutstockApply;
import com.yssoft.entity.inventory.TOutstockApplyDetail;
import com.yssoft.entity.inventory.TOutstockDetail;
import com.yssoft.entity.production.TLabels;
import com.yssoft.entity.production.TPackageCode;
import com.yssoft.mapper.inventory.TInstockDetailMapper;
import com.yssoft.mapper.inventory.TOutInStockMapper;
import com.yssoft.mapper.inventory.TOutstockApplyDetailMapper;
import com.yssoft.mapper.inventory.TOutstockApplyMapper;
import com.yssoft.mapper.inventory.TOutstockDetailMapper;
import com.yssoft.mapper.inventory.TOutstockMapper;
import com.yssoft.mapper.production.TLabelsMapper;
import com.yssoft.mapper.production.TPackageCodeMapper;
import com.yssoft.mapper.production.TWorksheetMapper;
import com.yssoft.utils.AppUserHelper;

import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @类名称: OutstockService
 * @类描述: 出库管理service
 * @作者: 洪丰
 * @创建时间:2018年5月17日 下午2:35:53
 */
@Service
public class OutstockService {
    
    @Resource
    private TOutInStockMapper outInStockMapper;
    @Resource
    private TOutstockApplyDetailMapper outstockApplyDetailMapper;
    @Resource
    private TOutstockApplyMapper outstockApplyMapper;
    @Resource
    private TOutstockDetailMapper outstockDetailMapper;
    @Resource
    private TOutstockMapper outstockMapper;
    @Resource
    private TLabelsMapper labelsMapper;
    @Resource
    private TWorksheetMapper worksheetMapper;
    @Resource
    private TPackageCodeMapper packageCodeMapper;
    @Resource
    private TInstockDetailMapper instockDetailMapper;
    
    /**
     * @方法名称: findOutstockApplyPage
     * @功能描述: 获取出库申请单及其明细
     * @作者: 洪丰
     * @创建时间:2018年5月17日 下午3:59:02
     * @param page
     * @param limit
     * @param companyId
     * @param source
     * @param state
     * @param deliveryDate
     * @return List<Map<String,Object>>
     */
    public List<Map<String, Object>> findOutstockApplyPage(int page, int limit, int companyId, String source, String state, String deliveryDate) {
        HashMap<String,Object> param = new HashMap<>();
        param.put("source",source);
        param.put("state",state);
        param.put("companyId",companyId);
        param.put("deliveryDate",deliveryDate);
        int start = ((page - 1) * limit);
		int end = limit;
		param.put("start", start);
		param.put("end", end);
		List<Map<String, Object>> outstockApplyList = outstockApplyMapper.selectOutstockApplyPage(param);
		for(Map<String, Object> paMap : outstockApplyList){
			List<Map<String, Object>> outApplyDetailList = 
					outstockApplyDetailMapper.selectOutAppDetailList(Integer.parseInt(paMap.get("id").toString()));
			paMap.put("outApplyDetailList", outApplyDetailList);
		}
        return outstockApplyList;
    }
    
    /**
     * @方法名称: findOutstockPage
     * @功能描述: 获取出库单及其明细
     * @作者: 洪丰
     * @创建时间:2018年5月17日 下午3:58:47
     * @param page
     * @param limit
     * @param companyId
     * @param source
     * @param state
     * @param deliveryDate
     * @return List<Map<String,Object>>
     */
    public List<Map<String, Object>> findOutstockPage(int page, int limit, int companyId, String source, String state, String deliveryDate) {
        HashMap<String,Object> param = new HashMap<>();
        param.put("source",source);
        param.put("state",state);
        param.put("companyId",companyId);
        param.put("deliveryDate",deliveryDate);
        int start = ((page - 1) * limit);
		int end = limit;
		param.put("start", start);
		param.put("end", end);
		List<Map<String, Object>> outstockList = outstockMapper.selectOutstockPage(param);
		for(Map<String, Object> paMap : outstockList){
			List<Map<String, Object>> outstockDetailList = 
					outstockDetailMapper.selectOutstockDetailList(Integer.parseInt(paMap.get("id").toString()));
			paMap.put("outstockDetailList", outstockDetailList);
			for(Map<String, Object> outDetailMap : outstockDetailList){
				List<Map<String, Object>> instockDetailList = 
						outstockDetailMapper.selectInDetaiByODId(Integer.parseInt(outDetailMap.get("id").toString()));
				outDetailMap.put("instockDetailList", instockDetailList);
			}
		}
        return outstockList;
    }
    
    /**
     * @方法名称: findOneOutstockApply
     * @功能描述: 获取出库申请及其明细
     * @作者: 洪丰
     * @创建时间:2018年5月17日 下午4:26:31
     * @param outstockApplyId
     * @return Map<String,Object>
     */
    public Map<String, Object> findOneOutstockApply(int outstockApplyId){
    	Map<String, Object> resultMap = new HashMap<String, Object>();
    	TOutstockApply oaEntity = outstockApplyMapper.selectByPrimaryKey(outstockApplyId);
    	resultMap.put("outstockApplyEntity", oaEntity);
    	List<Map<String, Object>> outApplyDetailList = 
				outstockApplyDetailMapper.selectOutAppDetailList(outstockApplyId);
    	resultMap.put("outAppDetailList", outApplyDetailList);
    	return resultMap;
    }
    
    /**
     * @方法名称: findInstockByMaterialId
     * @功能描述: 物料类别获取入库单名明细列表
     * @作者: 洪丰
     * @创建时间:2018年5月17日 下午5:31:47
     * @param outAppDetailId
     * @return List<Map<String,Object>>
     */
    public List<Map<String, Object>> findInstockByMaterialId(int outAppDetailId, String inStockData){
    	Map<String, Object> param = new HashMap<String, Object>();
    	param.put("id", outAppDetailId);
    	param.put("inStockData", inStockData);
    	List<Map<String, Object>> instockDetailList = outstockApplyDetailMapper.selectInstockDetailByMId(param);
    	return instockDetailList;
    }
    
    /**
     * @方法名称: findInstockBySfgId
     * @功能描述: 半成品类别获取入库单名明细列表
     * @作者: 洪丰
     * @创建时间:2018年5月17日 下午7:14:00
     * @param outAppDetailId
     * @param pType
     * @return List<Map<String,Object>>
     */
    public List<Map<String, Object>> findInstockBySfgId(int outAppDetailId, String inStockData){
    	Map<String, Object> param = new HashMap<String, Object>();
    	param.put("id", outAppDetailId);
    	param.put("inStockData", inStockData);
    	List<Map<String, Object>> instockDetailList = outstockApplyDetailMapper.selectInstockDetailBySfgId(param);
    	return instockDetailList;
    }
    
    /**
     * @方法名称: findInstockByWorksheeId
     * @功能描述: 成品类别获取入库单名明细列表
     * @作者: 洪丰
     * @创建时间:2018年5月17日 下午7:31:10
     * @param worksheeId
     * @return List<Map<String,Object>>
     */
    public List<Map<String, Object>> findInstockByWorksheeId(int worksheeId, String inStockData){
    	Map<String, Object> param = new HashMap<String, Object>();
    	param.put("id", worksheeId);
    	param.put("inStockData", inStockData);
    	List<Map<String, Object>> instockDetailList = outstockApplyDetailMapper.selectInDetailByWorksheeId(param);
    	return instockDetailList;
    }
    
    /**
     * @方法名称: checkProExist
     * @功能描述: 通过加工单id获取商品id
     * @作者: 洪丰
     * @创建时间:2018年5月17日 下午8:25:44
     * @param worksheeId
     * @return Integer
     */
    public Integer checkProExist(int worksheeId){
    	Integer pro = worksheetMapper.selectProIdByworksheetID(worksheeId);
    	return pro;
    }
    
    /**
     * @方法名称: checkBatchCodeExist
     * @功能描述: 判断批次码是否正确
     * @作者: 洪丰
     * @创建时间:2018年5月17日 下午7:48:52
     * @param code
     * @param companyId
     * @return TLabels
     */
    public TLabels checkBatchCodeExist(String code, int companyId, String type){
    	TLabels lEntity = new TLabels();
    	lEntity.settEId(companyId);
    	lEntity.setCode(code);
    	lEntity.setLabelStat("0");
    	 /** 溯源类型：0-无溯源 1-个体溯源 2-批量溯源*/
    	lEntity.setTraceType(type);
    	
    	return labelsMapper.selectOne(lEntity);
    }
    
    /**
     * @方法名称: findOneDetail
     * @功能描述: 获取出库申请明细
     * @作者: 洪丰
     * @创建时间:2018年5月17日 下午8:32:47
     * @param id
     * @return TOutstockApplyDetail
     */
    public TOutstockApplyDetail findOneDetail(int id){
    	TOutstockApplyDetail dEntity = this.outstockApplyDetailMapper.selectByPrimaryKey(id);
    	return dEntity;
    }
    
    /**
     * @方法名称: checkPaceageCodeExist
     * @功能描述: 校验包装码是否存在
     * @作者: 洪丰
     * @创建时间:2018年5月18日 上午9:19:23
     * @param code
     * @param companyId
     * @return TPackageCode
     */
    public TPackageCode checkPaceageCodeExist(String code, int companyId){
    	TPackageCode pcEntity = new TPackageCode();
    	pcEntity.settEId(companyId);
    	pcEntity.setCode(code);
    	pcEntity.setLabelStat("0");
    	return packageCodeMapper.selectOne(pcEntity);
    }
    
    /**
     * @方法名称: selectinDetailByLabelId
     * @功能描述: 根据标签id获取入库详细
     * @作者: 洪丰
     * @创建时间:2018年5月18日 上午9:33:29
     * @param lablesId
     * @return Map<String,Object>
     */
    public Map<String, Object> selectinDetailByLabelId(int lablesId){
    	return outstockApplyDetailMapper.selectinDetailByLabelId(lablesId);
    }

    /**
     * @方法名称: selectinDetailByPaceageId
     * @功能描述: 根据包装码id获取入库明细列表
     * @作者: 洪丰
     * @创建时间:2018年5月18日 上午9:50:33
     * @param paceageCodeId
     * @return List<Map<String,Object>>
     */
    public List<Map<String, Object>> selectinDetailByPaceageId(int paceageCodeId){
    	return outstockApplyDetailMapper.selectinDetailByPackCodeId(paceageCodeId);
    }
    
    /**
     * @方法名称: save
     * @功能描述: 保存出库信息
     * @作者: 洪丰
     * @创建时间:2018年5月19日 上午9:54:33
     * @param request
     * @param entity void
     */
    public void save (HttpServletRequest request,TOutstock entity){
    	String code = "CK" + Calendar.getInstance().getTimeInMillis();
    	if(null == entity.getId() || "".equals(entity.getId())){
    		entity.setDeleteFlag("0");
    		entity.setCode(code);
    		entity.setCreateTime(new Date());
    		entity.setCreatorId(AppUserHelper.getCurrentUserId(request));
    		entity.setCreatorName(AppUserHelper.getCurrentUserName(request));
    		entity.settEId(AppUserHelper.getCurrentCompanyId(request));
    		entity.setDeptId(AppUserHelper.getCurrentDeptId(request));
    		entity.setDeptName(AppUserHelper.getCurrentDeptName(request));
    		entity.setStat("2");
    		outstockMapper.insert(entity);
    		
    		TOutstockApply oaEntity = outstockApplyMapper.selectByPrimaryKey(entity.getOutstockApplyId());
    		TOutstockApply newOAEntity = new TOutstockApply();
    		newOAEntity.setId(oaEntity.getId());
    		newOAEntity.settOutstockId(entity.getId());
    		newOAEntity.setStat("2");
    		outstockApplyMapper.updateByPrimaryKeySelective(newOAEntity);
    		
    		//保存明细
    		for(TOutstockDetail dEntity : entity.getOutstockDetailList()){
    			dEntity.setDeleteFlag("0");
    			dEntity.setCreateTime(new Date());
    			dEntity.setCreatorId(AppUserHelper.getCurrentUserId(request));
    			dEntity.setCreatorName(AppUserHelper.getCurrentUserName(request));
    			dEntity.settEId(AppUserHelper.getCurrentCompanyId(request));
    			dEntity.setDeptId(AppUserHelper.getCurrentDeptId(request));
    			dEntity.setDeptName(AppUserHelper.getCurrentDeptName(request));
    			
    			dEntity.settOutstockId(entity.getId());
    			outstockDetailMapper.insert(dEntity);
    			
    			TOutstockApplyDetail oadEntity = outstockApplyDetailMapper.selectByPrimaryKey(dEntity.gettOutAppDId());
    			TOutstockApplyDetail newOADEntity = new TOutstockApplyDetail();
    			newOADEntity.setId(oadEntity.getId());
    			newOADEntity.setStat("2");
    			outstockApplyDetailMapper.updateByPrimaryKeySelective(newOADEntity);
        		
    			//保存中间表
    			for(TOutInStock oiEntity : dEntity.getOutInStockList()){
    				
    				oiEntity.settOutstockDetailId(dEntity.getId());
    				oiEntity.setCreateTime(new Date());
    				oiEntity.setDeleteFlag("0");
    				oiEntity.setCreatorId(AppUserHelper.getCurrentUserId(request));
    				oiEntity.setCreatorName(AppUserHelper.getCurrentUserName(request));
					oiEntity.setMargin(oiEntity.getMargin().subtract(oiEntity.getQuantity()));
    				outInStockMapper.insert(oiEntity);
    				TInstockDetail iDetail = instockDetailMapper.selectByPrimaryKey(oiEntity.gettInstockDetailId());
    				TInstockDetail newIDetail = new TInstockDetail();
    				newIDetail.setId(iDetail.getId());
					newIDetail.setMargin(iDetail.getMargin().subtract(oiEntity.getQuantity()));
    				instockDetailMapper.updateByPrimaryKeySelective(newIDetail);
    				
    				if(oiEntity.getLabelsList() != null){
    					for(TLabels lEntity : oiEntity.getLabelsList()){
    						lEntity.settOutstockDId(dEntity.getId());
    						labelsMapper.updateByPrimaryKeySelective(lEntity);
    					}
    				}
    			}
    		}
    	}
    }
    
    /**
     * @方法名称: findInstockAndLablesList
     * @功能描述: 获取个体溯源出库明细对应的标签码列表
     * @作者: 洪丰
     * @创建时间:2018年5月22日 下午7:38:01
     * @param outDetailId
     * @return List<Map<String,Object>>
     */
    public List<Map<String, Object>> findInstockAndLablesList(int outDetailId){
		List<Map<String, Object>> instockDetailList = outstockDetailMapper.selectInDetaiByODId(outDetailId);
		for(Map<String, Object> inMap : instockDetailList ){
			Map<String, Object> param = new HashMap<String, Object>();
			param.put("outId", outDetailId);
			param.put("inId", inMap.get("iId"));
			List<Map<String, Object>> labelsPacklList = outstockDetailMapper.selectLablePaceIsNotNull(param);
			for(Map<String, Object> labelMap : labelsPacklList ){
				List<Map<String, Object>> ls = new Gson().fromJson(labelMap.get("labelList").toString(), new TypeToken<List<Map<String,
						 Object>>>(){}.getType());
				labelMap.put("labelList", ls);
			}
			inMap.put("labelsAndPacklList", labelsPacklList);
			List<Map<String, Object>> labelsOnlylList = outstockDetailMapper.selectLablePaceIsNull(param);
			inMap.put("labelsOnlylList", labelsOnlylList);
		}
		return instockDetailList;
    } 
}


